#ifndef DISTRIBUTION_HPP
#define DISTRIBUTION_HPP

#include "error.hpp"
#include "random.hpp"

class distribution_i
{
protected:
        distribution_i ( void )
        {
        }
        
public:
        virtual ~distribution_i ( void )
        {
        }
        
        virtual double next ( void ) const = 0;
};

class constant_distribution_c : public distribution_i
{
        double probability_value;
public:
        virtual ~constant_distribution_c ( void )
        {
        }

        constant_distribution_c ( double probability_value ) :
                probability_value ( probability_value )
        {
                throw_if ( probability_value < 0.0 || probability_value > 1.0, ERROR_INVALID_ARGUMENTS );
        }
        
        virtual double next ( void ) const
        {
                return probability_value;
        }
};

class uniform_distribution_c : public distribution_i
{
        double lower_bound, upper_bound;
public:
        virtual ~uniform_distribution_c ( void )
        {
        }

        uniform_distribution_c ( double lower_bound, double upper_bound ) :
                lower_bound ( lower_bound ),
                upper_bound ( upper_bound )
        {
                throw_if ( lower_bound < 0.0 || upper_bound > 1.0 || lower_bound > upper_bound, ERROR_INVALID_ARGUMENTS );
        }
        
        virtual double next ( void ) const
        {
                double interval = upper_bound - lower_bound;
                return random_c::get ().next ( interval * PROBABILITY_SCALE ) / ( double ) PROBABILITY_SCALE + lower_bound;
        }
};

#endif

